package com.jeasonzhao.report.dataset;

import java.io.Serializable;

import com.jeasonzhao.commons.utils.Algorithms;
import com.jeasonzhao.commons.utils.DataTypes;
import com.jeasonzhao.report.codes.DataSetCellTypes;
import com.jeasonzhao.report.model.ReportColumn;
import com.jeasonzhao.report.model.ReportColumnValue;
import com.jeasonzhao.report.model.ReportColumnValueCollection;

public class DataCell implements Comparable<DataCell>,Serializable
{
    private static final long serialVersionUID = 1L;
    private DataSetCellTypes cellType = DataSetCellTypes.Normal;
    private boolean m_isVisiable = true;
    private int m_nColIndex = 0;
    private int m_nRowIndex = 0;
    private int m_nRowSpan = 0;
    private int m_nColSpan = 0;
    private String m_strText = null;
    private Object m_Value = null;
    private DataTypes m_DataType = DataTypes.STRING;
    private ReportColumn m_reportColumn = null;
    private int subtotalRowsCount;
    private String extraText;
    private Object m_Value4Sort = null;
    private ReportColumnValue m_ReportColumnValue = null;
    private ReportColumnValueCollection m_ReportColumnValueLimits = null;

    public ReportColumnValueCollection getReportColumnValueCollection()
    {
        return m_ReportColumnValueLimits;
    }

    public void setReportColumnValueCollection(ReportColumnValueCollection c)
    {
        m_ReportColumnValueLimits = c;
    }

    public DataCell()
    {
    }

    public DataCell(DataTypes dt)
    {
        m_DataType = dt;
    }

//    public Cell(Object value,String strText)
//    {
//        m_Value = value;
//        m_strText = strText;
//        if(null != value)
//        {
//            this.setDataType(DataTypes.fromClass(value.getClass()));
//        }
//    }

    public DataCell(DataCell cell)
    {
        if(null == cell)
        {
            return;
        }
        this.m_strText = cell.m_strText;
        this.m_Value = cell.m_Value;
        this.m_reportColumn = cell.m_reportColumn;
        this.m_nColIndex = cell.m_nColIndex;
        this.m_nRowIndex = cell.m_nRowIndex;
        this.m_nRowSpan = cell.m_nRowSpan;
        this.m_nColSpan = cell.m_nColSpan;
        this.m_DataType = cell.m_DataType;
        this.cellType = cell.cellType;
        this.m_isVisiable = cell.m_isVisiable;
        this.m_ReportColumnValue = cell.m_ReportColumnValue;
        this.m_ReportColumnValueLimits = cell.m_ReportColumnValueLimits;
        this.m_Value4Sort = cell.m_Value4Sort;
    }

    public static DataCell createFrom(DataCell cell)
    {
        DataCell ret = new DataCell(cell);
        ret.setColSpan(0);
        ret.setRowSpan(0);
        return ret;
    }

    public int hashCode()
    {
        return super.hashCode();
    }

    public static DataCell create(Object value)
    {
        DataCell ret = null;
        if(null != value && value instanceof DataCell)
        {
            ret = createFrom((DataCell) value);
            if(null != ret.getValue())
            {
                ret.setDataType(DataTypes.from(ret.getValue().getClass()));
            }
        }
        else
        {
            ret = new DataCell();
            ret.setValue(value);
            if(null != value)
            {
                ret.setDataType(DataTypes.from(value.getClass()));
            }
        }
        return ret;
    }

    public DataSetCellTypes getCellType()
    {
        return this.cellType == null ? DataSetCellTypes.Normal : cellType;
    }

    public String toString()
    {
        return this.getText();
    }

    public int getSubtotalRowsCount()
    {
        return subtotalRowsCount;
    }

    public String getExtraText()
    {
        return extraText;
    }

    public DataCell setCellType(DataSetCellTypes cellType)
    {
        this.cellType = cellType;
        return this;
    }

    public ReportColumnValue getReportColumnValue()
    {
        return m_ReportColumnValue;
    }

    public void setReportColumnValue(ReportColumnValue c)
    {
        m_ReportColumnValue = c;
    }

    public void setSubtotalRowsCount(int subtotalRowsCount)
    {
        this.subtotalRowsCount = subtotalRowsCount;
    }

    public void setExtraText(String extraText)
    {
        this.extraText = extraText;
    }

    public int getColIndex()
    {
        return m_nColIndex;
    }

    public int getColSpan()
    {
        return m_nColSpan;
    }

    public Object getValue()
    {
        return m_Value;
    }

    public int getRowSpan()
    {
        return m_nRowSpan;
    }

    public int getRowIndex()
    {
        return m_nRowIndex;
    }

    public DataCell setValue(Object Value)
    {
        this.m_Value = Value;
        return this;
    }

    public Object getValue4Sort()
    {
        return m_Value4Sort;
    }

    public String getRealSettingText()
    {
        return m_strText;
    }

    public String getText()
    {
        if(null == m_strText && null != m_Value)
        {
            return m_Value.toString();
        }
        else
        {
//        if(null != this.m_Value4Sort)
//        {
//            return m_Value4Sort.toString() + ">>>" + m_strText;
//        }
            return m_strText;
        }
    }

    public DataCell setText(String Text)
    {
        this.m_strText = Text;
        return this;
    }

    public DataCell setRowSpan(int RowSpan)
    {
        this.m_nRowSpan = RowSpan;
        return this;
    }

    public void setRowIndex(int RowIndex)
    {
        this.m_nRowIndex = RowIndex;
    }

    public void setColIndex(int ColIndex)
    {
        this.m_nColIndex = ColIndex;
    }

    public Range getRange()
    {
        if(m_nColSpan < 2 && m_nRowSpan < 2)
        {
            return null;
        }
        Range r = new Range();
        r.setBeginColIndex(m_nColIndex);
        if(m_nColSpan > 1)
        {
            r.setEndColIndex(m_nColIndex + m_nColSpan - 1);
        }
        else
        {
            r.setEndColIndex(m_nColIndex);
        }
        r.setBeginRowIndex(m_nRowIndex);
        if(m_nRowSpan > 1)
        {
            r.setEndRowIndex(m_nRowIndex + m_nRowSpan - 1);
        }
        else
        {
            r.setEndRowIndex(m_nRowIndex);
        }
        return r;
    }

    public ReportColumn getReportColumn()
    {
        return this.m_reportColumn;
    }

    public void setReportColumn(ReportColumn Tag)
    {
        this.m_reportColumn = Tag;
    }

    public DataTypes getDataType()
    {
        return m_DataType;
    }

    public void setDataType(DataTypes DataType)
    {
        this.m_DataType = DataType;
    }

    public boolean equals(Object obj)
    {
        if(null != obj)
        {
            if(obj instanceof DataCell)
            {
                DataCell cell = (DataCell) obj;
                if(null == cell || cell.m_Value == null || this.m_Value == null)
                {
                    return false;
                }
                else
                {
                    return cell.m_Value.equals(this.m_Value);
                }
            }
            else
            {
                return super.equals(obj);
            }
        }
        else
        {
            return false;
        }
    }

    public void setPosition(int nRow,int nCol)
    {
        this.m_nRowIndex = nRow;
        this.m_nColIndex = nCol;
    }

    public DataCell setColSpan(int colSpan)
    {
        this.m_nColSpan = colSpan;
        return this;
    }

    public void clear()
    {
        this.m_Value = null;
        this.m_reportColumn = null;
        this.m_strText = null;
    }

    public boolean isVisiable()
    {
        return m_isVisiable;
    }

    public DataCell setVisiable(boolean visiable)
    {
        this.m_isVisiable = visiable;
        return this;
    }

    public void setValue4Sort(Object obj)
    {
        m_Value4Sort = obj;
    }

    public int compareTo(DataCell cell)
    {
        if(null == cell)
        {
            return -1;
        }
        else if(null == this.getValue() || null == cell.getValue())
        {
            return null == this.getValue() ? -1 : 1;
        }
        else
        {
            int retValue = -1;
            if(this.m_Value4Sort != null || cell.m_Value4Sort != null)
            {
                Object ct = this.m_Value4Sort == null ? this.m_Value : this.m_Value4Sort;
                Object ct2 = cell.m_Value4Sort == null ? cell.m_Value : cell.m_Value4Sort;
                DataTypes dt = this.m_Value4Sort == null ? DataTypes.from(cell.m_Value4Sort.getClass()) :
                    DataTypes.from(this.m_Value4Sort.getClass());
                retValue = Algorithms.compare(dt,ct,ct2);
            }
            else
            {
                retValue = Algorithms.compare(this.getDataType(),this.getValue(),cell.getValue());
            }
            return retValue;
        }
    }
}
